/*
 * @Author: DaHuaZhuXi
 * @Date: 2020-10-13 16:42:13
 * @LastEditTime: 2021-01-13 21:18:10
 * @LastEditors: DaHuaZhuXi
 * @Description: 
 */
//根据id获取当前节点
export function getCurNodeById(id, nodes) {
  for (var i = 0; i < nodes.length; i++) {
    let item = nodes[i];
    if (item.id == id) return item;
    if (item.children) {
      let res = getCurNodeById(id, item.children);
      if (res) return res;
    }
  }
}

//获取字段某表指定id项目
export function getDataItem(key, id) {
  let o = data[key].find(e => e.id == id);
  return o2o(o);
}

/**
 * 创建人物
 * @param bool isRecruit 是否招募类别
 */
export function createPeos(isRecruit) {
  game.curSave.peos = [];
  let list = isRecruit ? data.peos.filter(p => p.$recruit == 1) : data.peos;
  for (let i = 0; i < config.peosUpdateCount; i++) {
    let index = common.random(0, list.length - 1);
    let peo = createPeo(list[index].id);
    game.curSave.peos.push(peo);
  }
  console.log("创建人物：");
  console.log(game.curSave.peos);
}

//创建单个人物
export function createPeo(typeId) {
  //先生成类别，根据类别赋予属性，再生成覆盖属性
  let o = data.peos.find(e => e.id == typeId);
  let peo = o2o(o);
  //增加潜力
  peo.poten = { hp: 0, str: 0, agi: 0, skill: 0, luck: 0, will: 0, sta: 0 };
  peo.potenUp = [];
  for (let s in peo.poten) {
    peo.poten[s] = common.getNumberInAppoint([
      [0, 0.3],
      [1, 0.4],
      [2, 0.2],
      [3, 0.1]
    ]);
  }
  peo.type = peo.id;
  peo.id = common.createUniqueId();
  peo.name = peo.class == 0 ? common.createRandomName() : o.type;
  peo.level = 0;
  peo.levelPoints = 0;
  peo.skillPoints = 0;
  peo.exp = 0;
  peo.hpMax = peo.hp;
  peo.equip = {
    head: '',
    other: '',
    body: '',
    leftHand: '',
    rightHand: '',
  };
  peo.x = 0;
  peo.y = 0;
  peo.buffs = [];
  peo.skills = [-1, 99]; //技能，默认添加移动和结束技能
  //数据统计相关
  peo.dates = 0;
  peo.battles = 0;
  peo.kills = 0;
  peo.damages = 0;
  peo.hits = 0; //命中
  peo.evages = 0; //闪避
  peo.hhs = 0; //暴击

  return peo;
}

//创建物品
export function createGoods() {
  game.curSave.goods = [];
  for (let i = 0; i < config.goodsUpdateCount; i++) {
    let type = common.random(0, data.goods.length - 2);
    let good = createGood(type);
    game.curSave.goods.push(good);
  }
  console.log("创建物品：");
  console.log(game.curSave.goods);
}

//创建单个物品
export function createGood(type) {
  //先生成类别，根据类别赋予属性，再生成覆盖属性
  let o = data.goods.find(e => e.id == type);
  let good = o2o(o);
  good.type = good.id;
  good.id = common.createUniqueId();
  if (good.type == 4) { //如果是饰品则增加创建效果
    good.effect = createEffect();
  }
  good.name = common.getTypeName("goods", good.type) + good.qua.toString();
  good.durMax = good.dur;
  return good;
}

//创建任务
export function createTasks() {
  game.curSave.tasks = [];
  for (let i = 0; i < config.tasksUpdateCount; i++) {
    let type = common.random(0, 0); //目前只生产0的任务
    let task = createTask(type);
    game.curSave.tasks.push(task);
  }
  console.log("创建任务：");
  console.log(game.curSave.tasks);
}

//创建单个任务
export function createTask(type) {
  let o = data.tasks.find(e => e.id == type);
  let task = {};
  task.id = common.createUniqueId();
  task.type = type;
  task.name = o.type;
  task.isCurrent = false;
  task.diff = common.random(1, 5);
  task.units = []; //目标单位
  task.places = []; //目标地点
  task.goodId = -1;
  task.goodCount = -1;

  task.price = task.diff * 200;
  task.canclePrice = Math.round(task.diff * 200 / 5);

  switch (type) {
    case 0: //收集素材(根据难度从“难度对应素材及数量”表中随机一个物品（及数量） -> 根据物品id获取对应单位 -> 从地点数据查出该单位所有可能的地点
      let typeCountList = data.task0.find(e => e.diff == task.diff).typeCount;
      typeCountList = JSON.parse(typeCountList);

      let random = common.random(0, typeCountList.length - 1);
      let typeCount = typeCountList[random];
      task.goodId = typeCount[0];
      task.goodCount = typeCount[1];

      // 根据物品id获取对应单位
      data.peos.forEach(peo => {
        let fall = JSON.parse(peo.$fall);
        fall.forEach(f => {
          if (f[0] == task.goodId) {
            task.units.push(parseInt(peo.id))
          }
        })
      })

      // 从地点数据查出该单位所有可能的地点
      data.places.forEach(place => {
        let unit = JSON.parse(place.unit);
        unit.forEach(f => {
          let id = parseInt(place.id);
          if (task.places.indexOf(id) == -1 && task.units.indexOf(f[0]) != -1) {
            task.places.push(id)
          }
        })
      })

      // let goodProb = targetUnit.$fall[goodId]; //物品掉落概率
      // console.log(goodId,goodProb);

      break;
    default:
      break;
  }

  return task;
}

//创建效果（装备）
function createEffect() {
  let effect = {};
  let keys = ['hpMax', 'str', 'agi', 'skill', 'luck', 'will', 'sta'];
  let count = common.random(1, 4);
  for (let i = 0; i < count; i++) {
    let key = keys.splice(common.random(0, keys.length - 1), 1);
    effect[key] = common.getNumberInAppoint([[1, 0.5], [2, 0.2], [3, 0.15], [4, 0.1], [5, 0.05]]);
  }
  return effect;
}

//根据数据表赋给对象属性和值(将 source 复制给 target )
export function o2o(source) {
  let target = {};
  for (let k in source) {
    let val = source[k];

    //字符串，描述和图标 读取字典表，减少数据存储
    if (k.indexOf('$') != -1) continue;

    if (isNaN(val)) {
      //对象
      if (val.indexOf("{") != -1) {
        val = val.replace(/'/g, "\"");
        target[k] = JSON.parse(val);
      }
      //数组
      else if (val.indexOf("[") != -1) {
        target[k] = JSON.parse(val);
      }
      //数字范围
      else if (val.indexOf("~") != -1) {
        let ary = val.split("~");
        target[k] = common.random(Number(ary[0]), Number(ary[1]))
      } else {
        target[k] = val;
      }
    }
    //数字类型
    else {
      target[k] = Number(val);
    }
  }
  return target;
}

//获取指定坐标的单位
export function getPointUnit(p, peos, elements, enemys) {
  for (let u of peos) {
    if (u.x == p[0] && u.y == p[1]) return u;
  }
  for (let u of elements) {
    if (u.x == p[0] && u.y == p[1] && u.seat) return u;
  }
  for (let u of enemys) {
    if (u.x == p[0] && u.y == p[1]) return u;
  }
  return
}

//获取技能执行范围内，技能类型及单位类型符合的单位数组 cur:执行主体
export function getTriggerRangeUnits(cur, range, skill, peos, elements, enemys) {
  let ary = [];
  range.forEach(point => {
    let unit = getPointUnit(point, peos, elements, enemys);
    if (!unit) return;
    if (
      (cur._type == "our" && unit._type == "enemy" && skill.class == 1) ||
      (cur._type == "our" && unit._type == "element" && unit.seat && skill.class == 1) ||
      (cur._type == "our" && unit._type == "our" && skill.class == 0) ||
      (cur._type == "enemy" && unit._type == "our" && skill.class == 1) ||
      (cur._type == "enemy" && unit._type == "element" && unit.seat && skill.class == 1) ||
      (cur._type == "enemy" && unit._type == "enemy" && skill.class == 0)
    ) {
      ary.push(unit)
    }
  })
  return ary;
}

//获取技能触发范围 p:指定技能范围一点
export function getTriggerRange(p, skillRange, map, cur) {
  let ary = [];
  if (skillRange.type == 1) {
    //触发范围类型：中心点
    return getPointRange(p, skillRange.trigger, map);
  } else if (skillRange.type == 2) {
    //触发范围类型：枚举
    for (let item of skillRange.trigger) {
      let pRange = getPointRange([cur.x, cur.y], item, map);
      if (common.indexOf2Array(p, pRange) != -1) return pRange;
    }
  }
}

//获取指定坐标结合坐标数组计算后的最终坐标组
export function getPointRange(p, pAry, map) {
  let ary = [];
  pAry.forEach(item => {
    let _p = [item[0] + p[0], item[1] + p[1]];
    if (0 <= _p[0] && _p[0] < map.cols && 0 <= _p[1] && _p[1] < map.rows) {
      ary.push(_p)
    }
  })
  return ary
}

//人物存储
export function peoSave(peo) {
  let cur = game.curSave.myTeam.find(p => p.id == peo.id);
  if (peo.hp < cur.hp) { cur.hp = peo.hp }
  cur.battles = peo.battles;
  cur.level = peo.level;
  cur.exp = peo.exp;
  cur.levelPoints = peo.levelPoints;
  cur.skillPoints = peo.skillPoints;
  cur.damages += peo._damages;
  cur.evages += peo._evages;
  cur.hits += peo._hits;
  cur.hhs += peo._hhs;
  cur.kills += peo._kills;
  cur.potenUp = JSON.parse(JSON.stringify(peo.potenUp));
  cur.buffs = JSON.parse(JSON.stringify(peo.buffs));
  cur.equip = JSON.parse(JSON.stringify(peo.equip));
  cur.skills = JSON.parse(JSON.stringify(peo.skills));
}

//获取攻击结果值
// export function getAtkResult(cur, unit, skill) {
//   console.log(unit);
//   let result = {
//     ba: 0, //破甲伤害
//     pa: 0, //穿甲伤害
//     bs: 0, //破盾伤害
//   }

//   return result;
// }
